<?php
/**
+-----------------------------------------------------------------------------------------------
* GouGuOPEN [ 左手研发，右手开源，未来可期！]
+-----------------------------------------------------------------------------------------------
* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
+-----------------------------------------------------------------------------------------------
* @Licensed 勾股OA，开源且可免费使用，但并不是自由软件，未经授权许可不能去除勾股OA的相关版权信息
+-----------------------------------------------------------------------------------------------
* @Author 勾股工作室 <hdm58@qq.com>
+-----------------------------------------------------------------------------------------------
*/
namespace app\lawcase\model;

use think\Model;
use think\facade\Db;

class NodeType extends Model
{
    // 定义案件类型
    /**
     * 获取案件类型映射表
     * @return array 返回案件类型映射数组，key为类型标识，value为类型名称
     */
    public static function getCaseTypes()
    {
        return [
            'civil' => '民事案件',
            'criminal' => '刑事案件',
            'administrative' => '行政案件',
            // 可以根据需要添加更多案件类型
        ];
    }

    // 设置当前模型对应的数据表名称
    protected $name = 'node_type';
    // 设置数据表前缀
    protected $prefix = 'oa_';
    // 设置主键
    protected $pk = 'id';
    // 设置自动时间戳
    protected $autoWriteTimestamp = true;
    protected $createTime = 'create_time';
    protected $updateTime = 'update_time';

    /**
     * 获取节点类型列表（带分页）
     * @param array $where 查询条件数组
     * @param array $param 分页参数，包含page、limit、order等
     * @return array 返回包含code、msg、data、count的数组，data为节点类型列表
     */
    public function getList($where, $param)
    {
        try {
            $order = empty($param['order']) ? ['sort' => 'asc', 'id' => 'asc'] : $param['order'];
            $page = empty($param['page']) ? 1 : (int)$param['page'];
            $limit = empty($param['limit']) ? config('app.page_size') : (int)$param['limit'];

            // 先获取总数
            $total = $this->where($where)->where('delete_time', 0)->count();

            // 如果没有数据，直接返回空结果
            if ($total == 0) {
                return ['code' => 0, 'msg' => '暂无数据', 'data' => [], 'count' => 0];
            }

            // 获取列表数据
            $list = $this->field('id, name, description, sort, create_time, update_time')
                ->where($where)
                ->where('delete_time', 0)
                ->order($order)
                ->page($page, $limit)
                ->select()
                ->each(function($item) {
                    // 处理时间字段
                    $item->create_time = $item->create_time ? intval($item->create_time) : 0;
                    $item->update_time = $item->update_time ? intval($item->update_time) : 0;
                    // 添加案件类型名称
                    $caseTypes = self::getCaseTypes();
                    $item->case_type_name = isset($caseTypes[$item->description]) ? $caseTypes[$item->description] : '未知类型';
                    return $item;
                });

            // 转换为数组
            $listArray = $list->toArray();
            
            return [
                'code' => 0, 
                'msg' => '获取成功', 
                'data' => $listArray,
                'count' => $total
            ];
        } catch (\Exception $e) {
            return ['code' => 1, 'msg' => '查询失败：' . $e->getMessage(), 'data' => [], 'count' => 0];
        }
    }

    /**
     * 添加节点类型
     * @param array $data 节点类型数据，必须包含name字段
     * @return array 返回操作结果，包含code、msg和data，data中包含新增的节点ID
     */
    public function add($data)
    {
        try {
            if (!isset($data['name'])) {
                return ['code' => 1, 'msg' => '添加节点类型失败: 缺少必要字段name'];
            }
            
            if (!isset($data['sort'])) {
                $data['sort'] = 100;
            }
            
            // 设置时间字段
            $now = time();
            $data['create_time'] = $now;
            $data['update_time'] = $now;
            $data['delete_time'] = 0;

            $insertId = $this->strict(false)->insertGetId($data);
            
            if (!$insertId) {
                return ['code' => 1, 'msg' => '添加节点类型失败'];
            }
            
            add_log('add', $insertId, $data);
            return ['code' => 0, 'msg' => '添加成功', 'data' => ['id' => $insertId]];
        } catch (\Exception $e) {
            return ['code' => 1, 'msg' => '添加节点类型失败：' . $e->getMessage()];
        }
    }

    /**
     * 编辑节点类型信息
     * @param array $data 节点类型数据，必须包含id字段
     * @return bool 返回操作结果，成功返回true，失败抛出异常
     * @throws \Exception 编辑失败时抛出异常
     */
    public function edit($data)
    {
        try {
            // 设置更新时间
            $data['update_time'] = time();
            
            $res = $this->strict(false)->where('id', $data['id'])->update($data);
            if ($res !== false) {
                add_log('edit', $data['id'], $data);
            }
            return $res !== false;
        } catch (\Exception $e) {
            throw new \Exception('编辑节点类型失败：' . $e->getMessage());
        }
    }

    /**
     * 删除节点类型（软删除）
     * @param int|array $ids 要删除的节点类型ID或ID数组
     * @return bool 返回操作结果，成功返回true，失败抛出异常
     * @throws \Exception 删除失败时抛出异常
     */
    public function remove($ids)
    {
        try {
            $ids = is_array($ids) ? $ids : [$ids];
            
            // 执行软删除
            $result = $this->where('id', 'in', $ids)->update(['delete_time' => time()]);
            
            if ($result !== false) {
                foreach ($ids as $id) {
                    add_log('delete', $id);
                }
            }
            
            return $result !== false;
        } catch (\Exception $e) {
            throw new \Exception('删除节点类型失败：' . $e->getMessage());
        }
    }

    /**
     * 获取节点类型详情
     * @param int $id 节点类型ID
     * @return array|null 返回节点类型详情数组，如果不存在返回null
     */
    public function getDetail($id)
    {
        $detail = $this->where(['id' => $id, 'delete_time' => 0])->find();
        return $detail ? $detail->toArray() : null;
    }

    /**
     * 更新节点类型排序
     * @param int $id 节点类型ID
     * @param int $sort 新的排序值
     * @return bool 返回操作结果，成功返回true，失败抛出异常
     * @throws \Exception 更新失败时抛出异常
     */
    public function updateSort($id, $sort)
    {
        try {
            $res = $this->where('id', $id)->update(['sort' => $sort]);
            if ($res !== false) {
                add_log('edit', $id, ['sort' => $sort]);
            }
            return $res !== false;
        } catch (\Exception $e) {
            throw new \Exception('更新排序失败：' . $e->getMessage());
        }
    }

    /**
     * 检查节点类型名称是否已存在
     * @param string $name 要检查的节点类型名称
     * @param string $caseType 案件类型标识
     * @param int $excludeId 需要排除的节点ID（用于编辑时检查）
     * @return bool 如果名称已存在返回true，否则返回false
     */
    public function nameExists($name, $caseType, $excludeId = 0)
    {
        $query = $this->where([
            ['name', '=', $name],
            ['description', '=', $caseType],
            ['delete_time', '=', 0]
        ]);

        if ($excludeId > 0) {
            $query->where('id', '<>', $excludeId);
        }

        return $query->count() > 0;
    }
}